package com.platform.comm.util;

import java.util.Iterator;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;

/**
 * Description: 工具类
 *
 * @author libin Created on 2019/8/12
 **/
public class Iterators {

    private Iterators() {
    }

    /**
     * Returns an iterator with {@code from} as first element. The subsequent elements are calculated by applying the {@code toNext}
     * function to the previous item. The iterator ends when {@code iterateWhile} returns {@code false}.
     * <p/>
     * Similar semantics as a for loop.
     * <p/>
     * Example: {@code iterateFor(0, i -> i+1, i -> i < 5) -> [0,1,2,3,4]}
     * <br/>
     * Beware: {@code iterateFor(0, i -> i++, i -> i < 5)}
     * will result in an infinite stream of [0,0,0,...]
     *
     * @param <T> taget class
     * @param from         the first element
     * @param iterateWhile the
     * @return Iterator
     */
    public static <T> Iterator<T> iterateFor(final T from, final Predicate<T> iterateWhile, final UnaryOperator<T> fn) {
        return new Iterator<T>() {
            private T current = from;

            @Override
            public boolean hasNext() {
                return iterateWhile.test(current);
            }

            @Override
            public T next() {
                T prev = current;
                current = fn.apply(current);
                return prev;
            }
        };
    }
}
